package com.loooooo.pm2024.modules.pm.service;


import com.loooooo.pm2024.config.RedisUtils;
import com.loooooo.pm2024.exception.MyBaseException;
import com.loooooo.pm2024.modules.pm.mapper.AttendanceMapper;
import com.loooooo.pm2024.modules.pm.model.Attendance;
import com.loooooo.pm2024.modules.pm.model.Task;
import com.loooooo.pm2024.modules.pm.model.TaskLog;
import com.loooooo.pm2024.modules.pm.selector.AttendanceSelector;
import com.loooooo.pm2024.modules.pm.selector.TaskLogSelector;
import com.loooooo.pm2024.modules.sys.model.PrettyUser;
import com.loooooo.pm2024.modules.sys.model.User;
import com.loooooo.pm2024.modules.sys.selector.UserSelector;
import com.loooooo.pm2024.modules.sys.service.UserService;
import com.loooooo.pm2024.security.SecurityUtils;
import com.loooooo.pm2024.service.IdService;
import com.loooooo.pm2024.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class AttendanceService {

    @Autowired
    AttendanceMapper attendanceMapper;
    @Autowired
    IdService idService;
    @Autowired
    UserService userService;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    TransactionTemplate transactionTemplate;

    public Attendance get(Long id) {
        return get(id, null);
    }

    public Attendance get(Long id, AttendanceSelector selector) {
        Attendance attendance = attendanceMapper.get(id);
        if (attendance != null && selector != null) {

        }
        return attendance;
    }


    public List<Attendance> list(AttendanceSelector selector) {
        List<Attendance> list = attendanceMapper.select(selector);
        if (list.size() > 0) {

            if (Objects.equals(1, selector.getWithPrettyActor())) {
                List<Long> userIdList = new ArrayList<>();
                for (Attendance task : list) {
                    appendIf(userIdList, task.getOwnerId());
                    appendIf(userIdList, task.getCreatedBy());
                    appendIf(userIdList, task.getUpdatedBy());
                }
                userIdList = userIdList.stream().distinct().collect(Collectors.toList());
                UserSelector userSelector = new UserSelector();
                userSelector.setIdList(userIdList);
                List<User> userList0 = userService.list(userSelector);
                List<PrettyUser> userList = userList0.stream().map(x -> PrettyUser.build(x)).collect(Collectors.toList());
                for (Attendance task : list) {
                    task.setCreatedByUser(findIf(userList, task.getCreatedBy()));
                    task.setUpdatedByUser(findIf(userList, task.getUpdatedBy()));
                    task.setOwnerUser(findIf(userList, task.getOwnerId()));
                }
            }
        }
        return list;
    }

    void appendIf(List<Long> list, Long id) {
        if (id != null) list.add(id);
    }

    PrettyUser findIf(List<PrettyUser> list, Long id) {
        if (id == null) return null;
        return list.stream().filter(x -> Objects.equals(x.getId(), id)).findAny().orElse(null);
    }

    public int count(AttendanceSelector selector) {
        return attendanceMapper.count(selector);
    }

    public int update(Attendance issue) {
        long now = System.currentTimeMillis();
        issue.setUpdatedAt(now);
        Long userId = SecurityUtils.loginedUserId();
        issue.setUpdatedBy(userId);

        if (issue.getId() == null || issue.isNewEntity() || issue.getId() <= 0L) {
            if (userId == null) {
                MyBaseException.throwMe(10401, "未登录");
            }
            if (issue.getId() == null || issue.getId() <= 0L) {
                issue.setId(idService.nextId());
            }
            if (issue.getOwnerId() == null) {
                MyBaseException.throwMe(10401, "用户未指定");
            }
            if (!StringUtils.hasText(issue.getType())) {
                MyBaseException.throwMe(10500, "类型未指定");
            }
            issue.setCreatedAt(now);
            issue.setCreatedBy(userId);
            if (issue.getClockAt() == null) {
                issue.setClockAt(now);
            }
            attendanceMapper.insert(issue);
        }
        return attendanceMapper.update(issue);
    }

    public int clockIn() {
        long now = System.currentTimeMillis();
        Long userId = SecurityUtils.loginedUserId();
        if (userId == null) {
            MyBaseException.throwMe(10401, "用户未登录");
        }
        Attendance attendance = new Attendance();
        attendance.setType("in");
        attendance.setOwnerId(userId);

        AttendanceSelector selector = new AttendanceSelector();
        selector.getTarget().setOwnerId(userId);
        selector.setOrderBy("id desc");
        selector.setPageSize(1);
        selector.setPageNo(1);
        List<Attendance> ls = list(selector);
        Attendance prev = ls.size() > 0 ? ls.get(0) : null;

        if (prev != null && "in".equalsIgnoreCase(prev.getType())) {
            //如果上一条是上班打卡，且是昨天
            LocalDateTime prevTime = DateUtils.toLocalDateTime(prev.getCreatedAt());
            LocalDate prevDay = prevTime.toLocalDate();
            LocalDate toDay = LocalDate.now();
            if (prevDay.isBefore(toDay)) {

            }
        }
        long time = DateUtils.localDate2Long(LocalDate.now().plusDays(1)) - DateUtils.localDateTime2Long(LocalDateTime.now());
        redisUtils.set("clock." + LocalDateTime.now().format(DateTimeFormatter.ofPattern("MMdd")) + "." + userId, "1", Duration.ofMillis(time));
        return update(attendance);
    }

    public int clockOff() {
        long now = System.currentTimeMillis();
        Long userId = SecurityUtils.loginedUserId();
        if (userId == null) {
            MyBaseException.throwMe(10401, "用户未登录");
        }
        Attendance attendance = new Attendance();
        attendance.setType("off");
        attendance.setOwnerId(userId);
        //long time = DateUtils.localDate2Long(LocalDate.now().plusDays(1)) - DateUtils.localDateTime2Long(LocalDateTime.now());

        redisUtils.set("clock." + LocalDateTime.now().format(DateTimeFormatter.ofPattern("MMdd")) + "." + userId, "", Duration.ofMillis(1));

        return update(attendance);
    }

    public boolean clocked(Long userId) {
        String s = redisUtils.get("clock." + LocalDateTime.now().format(DateTimeFormatter.ofPattern("MMdd")) + "." + userId);
        return "1".equalsIgnoreCase(s);
    }

    public int clock(String type) {
        long now = System.currentTimeMillis();
        Long userId = SecurityUtils.loginedUserId();
        if (userId == null) {
            MyBaseException.throwMe(10401, "用户未登录");
        }
        AttendanceSelector selector = new AttendanceSelector();
        selector.getTarget().setOwnerId(userId);
        selector.setOrderBy("id desc");
        selector.setPageSize(1);
        selector.setPageNo(1);
        List<Attendance> ls = list(selector);
        Attendance prev = ls.size() > 0 ? ls.get(0) : null;
        //
        if ("in".equalsIgnoreCase(type) || "clockIn".equalsIgnoreCase(type) || "clockin".equalsIgnoreCase(type)) {
            return clockIn();
        }
        return clockOff();
    }
}
